package com.ibm.cps.dft;
/**
 * directly Compute dft vector for input_vector
 * @author xuxiaomin
 *
 */
public class DFTOperator {

	/**
	 * Complex[] vector length=[input_vector/2]+1
	 * @param input_vector
	 * @return
	 */
	public static Complex[] computeDFT(Double[] input_vector){
		int w = input_vector!= null ? input_vector.length : -1;
		if(w <= 0)
			return null;
		
		Complex[] result = new Complex[w];
		
		for (int i = 0; i < result.length; i++) {
			result[i] = compute(input_vector,i);
		}
		
		/**
		 * optimize for DFT, dual partition
		 */
//		for (int i = half_w; i < result.length; i++) {
//			result[i] = result[w-1-i].conjugate();
//		}
		
		return result;
	}
	
	public Double[] ComputDFTModulusVecotr(Double[] batch) {
		Complex[] res = computeDFT(batch);
		if (res == null)
			return null;

		Double[] ret = new Double[res.length];

		for (int i = 0; i < res.length; i++) {
			ret[i] = res[i].modulus();
		}
		return ret;
	}
	
	/**
	 * 
	 * @param input_vector
	 * @param eleidx: current ele's index for input_vector
	 * @return
	 */
	private static Complex compute(Double[] input_vector, int eleidx)
	{
		int w = input_vector.length;
		Complex result = new Complex(0,0);
		for (int i = 0; i < input_vector.length; i++) {
			double xita = (-1)*2*Math.PI*eleidx*i/(double)w;
			double radis = input_vector[i];
			result.plusBy(new Complex(radis,xita,0));
		}
		result.timesBy(1/Math.sqrt(w));
		return result;
	}
	
}
